
/*
    基于 wx.request wx.uploadFile wx.downloadFile
    公用 http 请求类
    请求实例是一个包裹函数  prop同 httpMethod 一样( 不包括生命周期回调函数 )
*/
const comUtil = require('@/utils/common')
const RegexpConst = require('@/const/Regexp')
const path = require('path')
function HttpRequest(config) {
  // 默认配置
  this.baseURL = ''
  this.url = ''
  // http 请求方法
  this.httpMethod = null
  if (config && comUtil.isType(config, 'Object')) {
    comUtil.merge(this, config)
  }
  // 返回一个包裹函数
  return this.creatRequestIntance()
}

HttpRequest.prototype.creatRequestIntance = function() {
  const _this = this
  const { baseURL, interceptors } = _this

  return function wrapInstnce(requestParams) {
    // requestTask 实例
    let wxRequestTask
    const requestPro = new Promise((resolve, reject) => {
      const deepRequestProp = comUtil.extend(requestParams)
      const mergedBaseRequestProp = comUtil.mixin(deepRequestProp, _this)
      let waitRequestInterceptorsProp
      // 请求拦截
      if (interceptors && typeof interceptors.request === 'function') {
        waitRequestInterceptorsProp = interceptors.request(mergedBaseRequestProp)
        if (!waitRequestInterceptorsProp) {
          throw Error('Interceptors request function  must be return config object')
        }
      } else {
        waitRequestInterceptorsProp = mergedBaseRequestProp
      }

      const nextInWxRequestProp = {}
      // 如果请求 baseURL 不存在 或者 url 不是一个标准url
      if (RegexpConst.url.test(waitRequestInterceptorsProp.url || '') === false) {
        const _baseURL = waitRequestInterceptorsProp.baseURL || baseURL
        nextInWxRequestProp.url = path.join(_baseURL, waitRequestInterceptorsProp.url)
      } else {
        nextInWxRequestProp.url = waitRequestInterceptorsProp.url
      }
      // 合并配置项 到 wx.request 参数
      comUtil.mixin(nextInWxRequestProp, waitRequestInterceptorsProp)
      // 响应拦截
      const interceptorResponse = interceptors.response
      // 最终配置 in wx.request
      const finallyRequestConfig = Object.assign({}, nextInWxRequestProp, {
        success(response) {
          // 设置响应参数
          const mergeResponse = Object.assign({
            config: nextInWxRequestProp
          }, response)
          // 响应拦截存在
          if (interceptorResponse && typeof interceptorResponse === 'function') {
            const interceptorResponseRes = interceptorResponse(mergeResponse, null)
            if (interceptorResponseRes instanceof Promise) {
              interceptorResponseRes.then(res => {
                resolve(res)
              }).catch(err => {
                reject(err)
              })
            } else {
              resolve(interceptorResponseRes)
            }
          } else {
            resolve(mergeResponse)
          }
        },
        fail(error) {
          const errorResponse = {
            error,
            config: nextInWxRequestProp
          }
          // 响应拦截存在
          if (interceptorResponse && typeof interceptorResponse === 'function') {
            const interceptorResponseRes = interceptorResponse(null, errorResponse)
            if (interceptorResponseRes instanceof Promise) {
              interceptorResponseRes.then(res => {
                resolve(res)
              }).catch(err => {
                reject(err)
              })
            } else {
              reject(interceptorResponseRes)
            }
          } else {
            reject(errorResponse)
          }
        }
      })
      if (!_this.httpMethod) {
        throw Error('httpMethod is not defined')
      }
      if (typeof _this.httpMethod !== 'function') {
        throw Error('httpMethod type must be Function')
      }
      wxRequestTask = _this.httpMethod(finallyRequestConfig)
    })
    // 给 实例promise对象 添加方法
    // 获取 requestTask对象
    requestPro._getTask = () => {
      return wxRequestTask
    }
    // 中断 requestTask对象请求
    requestPro._abortTask = () => {
      if (wxRequestTask) {
        return wxRequestTask.abort()
      }
    }
    return requestPro
  }
}

module.exports = HttpRequest
